#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import cv2
import numpy as np
import pytesseract
import sys
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import imagehash

import logging
import json
from pydash import py_
from PIL import Image
import struct
from sklearn.neighbors import BallTree
import cut_card
import time
import random


def setup_custom_logger(name):
    formatter = logging.Formatter(fmt='%(asctime)s %(levelname)-8s %(message)s',
                                  datefmt='%Y-%m-%d %H:%M:%S')
    # handler = logging.FileHandler('log.txt', mode='w')
    # handler.setFormatter(formatter)
    screen_handler = logging.StreamHandler(stream=sys.stdout)
    screen_handler.setFormatter(formatter)
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)
    # logger.addHandler(handler)
    logger.addHandler(screen_handler)
    return logger


logger = setup_custom_logger('app')


def selectCardTest():
    # path = '/home/liusen/IdeaWorkspace/wechat-jump/mijing/201809-special-选牌.png'
    path = '/home/liusen/IdeaWorkspace/wechat-jump/mijing2/img.png'

    img = cv2.imread(path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img1 = cut_card.cut_card(img, 1)
    img2 = cut_card.cut_card(img, 2)
    img3 = cut_card.cut_card(img, 3)
    img4 = cut_card.cut_card(img, 4)

    img4 = cv2.cvtColor(img4, cv2.COLOR_RGB2BGR)

    # cv2.imwrite('/home/liusen/IdeaWorkspace/wechat-jump/mijing3/bolingkelitujizhe.png', img4)

    # print(cut_card.calcImagepHash(img1))
    plt.subplot(221), plt.imshow(img1)
    plt.subplot(222), plt.imshow(img2)
    plt.subplot(223), plt.imshow(img3)
    plt.subplot(224), plt.imshow(img4)

    plt.show()


def pHashTest():
    hash_size = 16

    img1 = cv2.imread('/home/liusen/IdeaWorkspace/wechat-jump/mijing_card/5a9f53a0aa49f1cc6440c277P3l70Kbp.png')
    h, w = img1.shape[:2]
    h = round(h * 0.53)
    img1 = img1[0:h, 0:w]
    img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
    hash1 = imagehash.phash(Image.fromarray(img1), hash_size=hash_size)
    print(hash1)

    img2 = cv2.imread('/home/liusen/IdeaWorkspace/wechat-jump/mijing_card/5a9f53a3fb758a8b148bd22475wjY4C5.png')
    h, w = img2.shape[:2]
    h = round(h * 0.53)
    img2 = img2[0:h, 0:w]
    img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
    hash2 = imagehash.phash(Image.fromarray(img2), hash_size=hash_size)
    print(hash2)

    # print(hammingDist2(hash1, hash2))
    print(cut_card.hammingDist2(str(hash1), str(hash2), hash_size))
    print(cut_card.hammingDist2(str("00000000000000000000000000000000"), str("ffffffffffffffffffffffffffffffff"),
                                hash_size))
    print(cut_card.hammingDist2(str("ffffffffffffffffffffffffffffffff"), str("00000000000000000000000000000000"),
                                hash_size))

    X = np.random.random((10, 3))
    print(X)
    # 000201e20ff84ff81f7c1f183e3c383c3c1c3e3e1e3e0fbe22fc001000006006
    str1 = "000201e20ff84ff81f7c1f183e3c383c3c1c3e3e1e3e0fbe22fc001000006006"
    str2 = "000207fe0ffc5f385f387e1c379621be743e7c1c7c603438720040860007c407"
    a = cut_card.hammingDistToArray(str1)
    b = cut_card.hammingDistToArray(str2)
    print(a)
    print(b)
    print(cut_card.arrayToHammingDist(a) == str1)
    print(cut_card.arrayToHammingDist(b) == str2)


def ballTreeTest():
    ballt, index_data, item_dict = cut_card.cardDataToBallTree()
    distances, neighbors = ballt.query(
        [cut_card.hammingDistToArray('c0c535312615cb9c8df311fef808701858e9cef2a1b4cce61a77720ddcc73447')], k=10)
    print(neighbors)  # Row n has the nth vector's k closest neighbors.
    print([index_data[x] for x in neighbors[0]])  # Row n has the nth vector's k closest neighbors.
    print(distances)  # Same idea but the hamming distance to neighbors.
    sys.exit()


# def hammingDistToArray(s):
#     n = 1
#     return [int(s[i:i + n], 16) / int("f" * n, 16) for i in range(0, len(s), n)]

# def arrayToHammingDist(arr):
#     n = 1
#     return "".join(['{:08x}'.format(round(f * int("f" * n, 16)), 'x') for f in arr])

def arrayToHammingDistTest():
    print("c0c52531a635cb9c8de331def8087a1958e9c6f2e1bccce61a373b0ddcc334c6")
    print(cut_card.hammingDistToArray("c0c52531a635cb9c8de331def8087a1958e9c6f2e1bccce61a373b0ddcc334c6"))
    print(cut_card.arrayToHammingDist(
        cut_card.hammingDistToArray("c0c52531a635cb9c8de331def8087a1958e9c6f2e1bccce61a373b0ddcc334c6")))
    sys.exit()

def tweakParam():
    img = cv2.imread("/home/liusen/IdeaWorkspace/wechat-jump/mijing/04.png")
    # img = cv2.imread("/home/liusen/IdeaWorkspace/wechat-jump/mijing/201809-special-10张牌.png")
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

    img = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
    # img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    img = img[555:720, 300:1110]
    # FILTER_MIN = np.array([0, 0, 135], np.uint8)
    # FILTER_MAX = np.array([255, 93, 255], np.uint8)
    # frame_threshed = cv2.inRange(img, FILTER_MIN, FILTER_MAX)
    # img = cv2.bitwise_or(img, img, mask=frame_threshed)
    #
    # FILTER_MIN = np.array([20, 10, 0], np.uint8)
    # FILTER_MAX = np.array([35, 104, 255], np.uint8)
    # frame_threshed = cv2.bitwise_not(cv2.inRange(img, FILTER_MIN, FILTER_MAX))
    # img = cv2.bitwise_or(img, img, mask=frame_threshed)
    # # plt.imshow(frame_threshed)
    # # plt.show()
    # # sys.exit()
    img = cv2.cvtColor(img, cv2.COLOR_HSV2RGB)

    img = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
    cv2.namedWindow('image', cv2.WINDOW_AUTOSIZE)
    cv2.createTrackbar('R1', 'image', 88, 255, nothing)
    cv2.createTrackbar('R2', 'image', 110, 255, nothing)
    cv2.createTrackbar('G1', 'image', 165, 255, nothing)
    cv2.createTrackbar('G2', 'image', 241, 255, nothing)
    cv2.createTrackbar('B1', 'image', 202, 255, nothing)
    cv2.createTrackbar('B2', 'image', 255, 255, nothing)
    switch = '0:OFF\n1:ON'
    cv2.createTrackbar(switch, 'image', 0, 1, nothing)

    img_crop = img
    while (1):
        size = img.shape
        cv2.imshow('image', img_crop)
        k = cv2.waitKey(1) & 0xFF
        if k == 113:
            break
        r1 = cv2.getTrackbarPos('R1', 'image')
        r2 = cv2.getTrackbarPos('R2', 'image')
        g1 = cv2.getTrackbarPos('G1', 'image')
        g2 = cv2.getTrackbarPos('G2', 'image')
        b1 = cv2.getTrackbarPos('B1', 'image')
        b2 = cv2.getTrackbarPos('B2', 'image')
        FILTER_MIN = np.array([r1, g1, b1], np.uint8)
        FILTER_MAX = np.array([r2, g2, b2], np.uint8)
        # FILTER_MIN = np.array([r], np.uint8)
        # FILTER_MAX = np.array([255], np.uint8)
        # frame_threshed = cv2.bitwise_not(cv2.inRange(img, FILTER_MIN, FILTER_MAX))
        frame_threshed = cv2.inRange(img, FILTER_MIN, FILTER_MAX)
        img_crop = cv2.bitwise_or(img, img, mask=frame_threshed)
        img_crop = cv2.cvtColor(img_crop, cv2.COLOR_HSV2BGR)
        s = cv2.getTrackbarPos(switch, 'image')
        if s == 1:
            logger.debug(pytesseract.image_to_string(img_crop, lang='chi_sim'))
        time.sleep(0.1)

    cv2.destroyAllWindows()


def colorAnalysis(img):
    hsv_map = np.zeros((180, 256, 3), np.uint8)
    h, s = np.indices(hsv_map.shape[:2])
    hsv_map[:, :, 0] = h
    hsv_map[:, :, 1] = s
    hsv_map[:, :, 2] = 255
    hsv_map = cv2.cvtColor(hsv_map, cv2.COLOR_HSV2RGB)

    hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)

    h = cv2.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
    h = np.clip(h * 32, 0, 1)
    vis = hsv_map * h[:, :, np.newaxis] / 255.0

    plt.subplot(221), plt.imshow(hsv_map)
    plt.subplot(222), plt.imshow(vis)
    plt.subplot(223), plt.imshow(hsv)
    plt.subplot(224), plt.imshow(img)
    # logger.debug(
    #     pytesseract.image_to_string(img, lang='eng', config='--psm 10 --oem 3 -c tessedit_char_whitelist=0123456789')
    # )

    # plt.imshow(img)
    plt.show()

    # 去掉放大的卡牌 1188 551


def showPic():
    # img = cv2.imread("/home/liusen/IdeaWorkspace/wechat-jump/mijing/201809-special-10张牌.png")
    img = cv2.imread("/home/liusen/IdeaWorkspace/wechat-jump/mijing/201809-scene-风语林地.png")
    # raw = cv2.imread("/home/liusen/IdeaWorkspace/wechat-jump/mijing/201809-special-10张牌.png")
    # raw = cv2.cvtColor(raw, cv2.COLOR_BGR2RGB)

    # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    img = img[555:720, 300:1110]
    # raw = raw[555:720, 300:1110]

    FILTER_MIN = np.array([88, 165, 187], np.uint8)
    FILTER_MAX = np.array([110, 255, 255], np.uint8)
    frame_threshed = cv2.inRange(img, FILTER_MIN, FILTER_MAX)
    img = cv2.bitwise_or(img, img, mask=frame_threshed)
    img = cv2.cvtColor(img, cv2.COLOR_HSV2RGB)
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    kernel = np.ones((3, 3), np.uint8)
    # img2 = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
    # img2 = cv2.morphologyEx(img2, cv2.MORPH_CLOSE, kernel)
    img2 = cv2.dilate(img, kernel, iterations=4)
    gray = cv2.cvtColor(img2, cv2.COLOR_RGB2GRAY)

    # edges = cv2.Canny(gray, 50, 150, apertureSize=3)

    # plt.subplot(311), plt.imshow(img)
    # # plt.subplot(312), plt.imshow(edges)
    # plt.subplot(313), plt.imshow(img2)
    # mng = plt.get_current_fig_manager()
    # mng.resize(*mng.window.maxsize())
    # plt.show()
    # sys.exit()

    # edges = cv2.Canny(gray, 50, 150, apertureSize=3)

    # cv2.namedWindow('image', cv2.WINDOW_AUTOSIZE)
    # cv2.createTrackbar('R1', 'image', 53, 200, nothing)
    # cv2.createTrackbar('R2', 'image', 52, 100, nothing)
    # cv2.createTrackbar('G1', 'image', 19, 100, nothing)
    #
    # while (1):
    #     img_crop = gray.copy()
    #     threshold = cv2.getTrackbarPos('R1', 'image')  # 57
    #     minLineLength = cv2.getTrackbarPos('R2', 'image')  # 52
    #     maxLineGap = cv2.getTrackbarPos('G1', 'image')  # 19
    #     lines = cv2.HoughLinesP(image=gray, rho=1, theta=np.pi / 180, threshold=threshold, lines=np.array([]),
    #                             minLineLength=minLineLength, maxLineGap=maxLineGap)
    #     if lines is not None:
    #         for line in lines:
    #             for x1, y1, x2, y2 in line:
    #                 cv2.line(img_crop, (x1, y1), (x2, y2), (111, 111, 111), 2)
    #     cv2.imshow('image', img_crop)
    #     k = cv2.waitKey(1) & 0xFF
    #     if k == 113:
    #         break
    #     time.sleep(0.1)
    #
    # cv2.destroyAllWindows()
    # sys.exit()

    gray1 = np.zeros(gray.shape, np.uint8)
    gray11 = np.zeros(gray.shape, np.uint8)
    lines = cv2.HoughLinesP(image=gray, rho=1, theta=np.pi / 180, threshold=53, lines=np.array([]),
                            minLineLength=52, maxLineGap=19)
    if lines is not None:
        for line in lines:
            for x1, y1, x2, y2 in line:
                cv2.line(gray1, (x1, y1), (x2, y2),
                         (255, 255, 255), 2)

    # gray3 = cv2.bitwise_or(raw, raw, mask=cv2.bitwise_not(gray1))

    # img = cv2.cvtColor(img, cv2.COLOR_HSV2RGB)
    # gray3 = cv2.absdiff(img, gray1)

    gray2 = gray1[150:, :]
    # gray2 = 255 - gray2
    # kernel = np.ones((3,3),np.uint8)
    # gray2 = cv2.erode(gray2,kernel,iterations = 1)
    img_row_sum = np.sum(gray2, axis=0)
    zipped = np.asarray(
        list(filter(lambda x: x != 0,
                    list(map(lambda x: x[0] if x[1] != 0 else 0,
                             list(zip(range(1, len(img_row_sum)), img_row_sum)))))))
    # logger.debug(img_row_sum)
    # res = [np.split(i, np.flatnonzero(np.abs(np.diff(i)) >= 1) + 1) for i in zipped]
    # logger.debug(zipped)
    # logger.debug(res)
    # logger.debug(gray2)

    # imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 1, 255, 0)
    thresh = cv2.bitwise_not(thresh)
    _, contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # logger.debug(list(map(lambda cnt: cv2.arcLength(cnt, True), contours)))
    filteredContours = contours

    def filteredContourFunc(cnt):
        x, y, w, h = cv2.boundingRect(cnt)
        return 2500 < w * h < 13000

    def filteredContourFunc2(cnt):
        x, y, w, h = cv2.boundingRect(cnt)
        return w * h

    filteredContours = list(filter(filteredContourFunc, contours))

    cardLocations = list(map(filteredContourFunc2, contours))
    logger.debug('cardLocations:{}'.format(cardLocations))

    contoursImg = cv2.drawContours(gray11, filteredContours, -1, (255, 255, 255), 3)

    img_crop = gray11.copy()
    for cnt in filteredContours:
        x, y, w, h = cv2.boundingRect(cnt)
        img_crop = cv2.rectangle(img_crop, (x, y), (x + w, y + h), (255, 0, 0), 2)

    # cv2.namedWindow('image', cv2.WINDOW_AUTOSIZE)
    # cv2.createTrackbar('R1', 'image', 1, 50, nothing)
    #
    # while (1):
    #     img_crop = gray11.copy()
    #     r1 = cv2.getTrackbarPos('R1', 'image')
    #     contours_crop = contours[:r1]
    #     for cnt in contours_crop:
    #         x, y, w, h = cv2.boundingRect(cnt)
    #         logger.debug("x {} y {} w {} h {}".format(x, y, w, h))
    #         img_crop = cv2.rectangle(img_crop, (x, y), (x + w, y + h), (111, 0, 0), 2)
    #
    #     img_crop = cv2.drawContours(img_crop, contours_crop, -1, (255, 255, 255), 3)
    #     cv2.imshow('image', img_crop)
    #     k = cv2.waitKey(1) & 0xFF
    #     if k == 113:
    #         break
    #     time.sleep(0.1)
    # sys.exit()

    # plt.subplot(411), plt.imshow(gray)
    plt.subplot(411), plt.imshow(gray1)
    plt.subplot(412), plt.imshow(img_crop)

    plt.subplot(413), plt.imshow(thresh)
    plt.subplot(414), plt.imshow(contoursImg)
    # plt.imshow(img)
    mng = plt.get_current_fig_manager()
    mng.resize(*mng.window.maxsize())
    plt.show()


if __name__ == '__main__':
    # img = cv2.imread('/home/liusen/IdeaWorkspace/wechat-jump/mijing3/bolingkelitujizhe.png')
    # print(cut_card.calcImagepHash(img))

    # img = cv2.imread('/home/liusen/IdeaWorkspace/wechat-jump/mijing2/img.png')
    # print(cut_card.handleSelectCard(img))
    # tweakParam()
    showPic()
    sys.exit()
    # selectCardTest()
    # cardDataInit()
    # sys.exit()

    # img = cv2.imread("/home/liusen/IdeaWorkspace/wechat-jump/mijing_card/5a9f53a0aa49f1cc6440c277P3l70Kbp.png")
    # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # plt.imshow(img), plt.show()

    # img = cv2.imread("/home/liusen/IdeaWorkspace/wechat-jump/mijing/201809-scene-伊芙琳教堂.png")
    # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # plt.imshow(img), plt.show()

    # 透视变换
    img = cv2.imread("/home/liusen/IdeaWorkspace/wechat-jump/mijing/201809-special-10张牌.png")
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    img = img[555:720, 300:1110]
    # img = cv2.imread('/home/liusen/IdeaWorkspace/wechat-jump/mijing/201809-scene-伊芙琳教堂.png')
    # rows, cols, ch = img.shape
    pts1 = np.float32([[43, 100], [400, 45], [47, 164], [400, 109]])
    pts2 = np.float32([[0, 0], [1100, 0], [0, 400], [1100, 400]])
    # pts1 = np.float32([[43, 100], [453, 626], [359, 719], [460, 703]])
    # pts2 = np.float32([[0, 0], [400, 0], [0, 400], [400, 400]])
    M = cv2.getPerspectiveTransform(pts1, pts2)
    dst = cv2.warpPerspective(img, M, (1100, 400))
    plt.subplot(211), plt.imshow(img), plt.title('Input')
    plt.subplot(212), plt.imshow(dst), plt.title('Output')
    plt.show()

    # # 仿射变换
    # img = cv2.imread('/home/liusen/IdeaWorkspace/wechat-jump/mijing/201809-scene-伊芙琳教堂.png')
    # rows, cols, ch = img.shape
    # pts1 = np.float32([[353, 651], [453, 627], [360, 718]])
    # # pts2 = np.float32([[0, 0], [200, 0], [200, 0]])
    # pts2 = np.float32([[345, 621], [453, 627], [345, 718]])
    #
    # M = cv2.getAffineTransform(pts1, pts2)
    # dst = cv2.warpAffine(img, M, (cols, rows))
    # plt.subplot(121), plt.imshow(img), plt.title('Input')
    # plt.subplot(122), plt.imshow(dst), plt.title('Output')
    # plt.show()

    sys.exit(0)
